package com.pj.app.auraSimulator.parsers;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.pj.lib.aura.connection.AuraTypeModel;
import com.pj.lib.aura.connection.UserModel;

public class XMLParser {
	private File file;
	
	private ArrayList<AuraTypeModel> auraTypes;
	private ArrayList<UserXMLModel> users;
	private int length;
	
	private XMLParser(File file) {this.file = file;};
	
	public static XMLParser getInstance(File file) {
		return new XMLParser(file);
	}
	
	public void parse() throws ParserConfigurationException, SAXException, IOException {
		if(file != null) {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			
			NodeList auraTypesNode = doc.getElementsByTagName("auraTypes"); 
			createAuraTypes(auraTypesNode.item(0));
			NodeList lengthNode = doc.getElementsByTagName("length");
			getLength((Element) lengthNode.item(0));
			NodeList usersNode = doc.getElementsByTagName("users");
			createUsers(usersNode.item(0));
		} 
	}

	private void createUsers(Node item) throws ParserConfigurationException, SAXException, IOException {
		NodeList auraTypesNodes = item.getChildNodes();
		
		users = new ArrayList<UserXMLModel>(auraTypesNodes.getLength());
		
		for(int i = 0; i <auraTypesNodes.getLength(); i++) {
			
			Node auraTypeNode = auraTypesNodes.item(i);
			if(auraTypeNode.getNodeType() == Node.ELEMENT_NODE) {
				UserXMLModel atModel = new UserXMLModel();
				Element el = (Element) auraTypeNode;
				
				NodeList firstnl = el.getElementsByTagName("login");
				Element firstnlElement = (Element) firstnl.item(0);
				NodeList fstNm = firstnlElement.getChildNodes();
				atModel.nickName = ((Node) fstNm.item(0)).getNodeValue();
				
				firstnl = el.getElementsByTagName("password");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.password= ((Node) fstNm.item(0)).getNodeValue();
				
				firstnl = el.getElementsByTagName("kml");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.kmlFile= ((Node) fstNm.item(0)).getNodeValue();
				
				String fullFileName = file.getParent() +System.getProperty("file.separator")+ atModel.kmlFile;
				KMLParser kmlParser = KMLParser.getInstance(new File(fullFileName));
				kmlParser.parse();
				atModel.coords = kmlParser.getCoords();
				
				firstnl = el.getElementsByTagName("start_time");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.startTime = Integer.valueOf(((Node) fstNm.item(0)).getNodeValue());
				
				firstnl = el.getElementsByTagName("end_time");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.endTime = Integer.valueOf(((Node) fstNm.item(0)).getNodeValue());
				
				firstnl = el.getElementsByTagName("events");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.events= ((Node) fstNm.item(0)).getNodeValue();
				
				
				
				users.add(atModel);
				
				
			}
		}
		
	}

	private void getLength(Element item) {
		NodeList fstNm = item.getChildNodes();
		length = Integer.valueOf(((Node) fstNm.item(0)).getNodeValue());
		System.out.println("Length: " + length);
	}

	private void createAuraTypes(Node auraTypesNode) {
		NodeList auraTypesNodes = auraTypesNode.getChildNodes();
		
		auraTypes = new ArrayList<AuraTypeModel>(auraTypesNodes.getLength());
		
		for(int i = 0; i <auraTypesNodes.getLength(); i++) {
			
			Node auraTypeNode = auraTypesNodes.item(i);
			if(auraTypeNode.getNodeType() == Node.ELEMENT_NODE) {
				AuraTypeModel atModel = new AuraTypeModel();
				Element el = (Element) auraTypeNode;
				
				NodeList firstnl = el.getElementsByTagName("code");
				Element firstnlElement = (Element) firstnl.item(0);
				NodeList fstNm = firstnlElement.getChildNodes();
				atModel.code = ((Node) fstNm.item(0)).getNodeValue();
				
				firstnl = el.getElementsByTagName("name");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.name = ((Node) fstNm.item(0)).getNodeValue();
				
				firstnl = el.getElementsByTagName("radius");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.radius= Integer.valueOf(((Node) fstNm.item(0)).getNodeValue());
				
				firstnl = el.getElementsByTagName("leaving_time");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				atModel.leavingTime = Integer.valueOf(((Node) fstNm.item(0)).getNodeValue());
				
				firstnl = el.getElementsByTagName("actions");
				firstnlElement = (Element) firstnl.item(0);
				fstNm = firstnlElement.getChildNodes();
				for(int j = 0; j <fstNm.getLength(); j++) {
					Node node = fstNm.item(j);
					if(node.getNodeType() == Node.ELEMENT_NODE) {
						Element el1 = (Element) auraTypeNode;
						
						NodeList firstnl1 = el1.getElementsByTagName("enter");
						Element firstnlElement1 = (Element) firstnl1.item(0);
						NodeList fstNm1 = firstnlElement1.getChildNodes();
						atModel.actionEnter = ((Node) fstNm1.item(0)).getNodeValue();

						firstnl1 = el1.getElementsByTagName("temp_leave");
						firstnlElement1 = (Element) firstnl1.item(0);
						fstNm1 = firstnlElement1.getChildNodes();
						atModel.actionTempLeave = ((Node) fstNm1.item(0)).getNodeValue();
						
						firstnl1 = el1.getElementsByTagName("return");
						firstnlElement1 = (Element) firstnl1.item(0);
						fstNm1 = firstnlElement1.getChildNodes();
						atModel.actionReturn = ((Node) fstNm1.item(0)).getNodeValue();
						
						firstnl1 = el1.getElementsByTagName("exit");
						firstnlElement1 = (Element) firstnl1.item(0);
						fstNm1 = firstnlElement1.getChildNodes();
						atModel.actionExit = ((Node) fstNm1.item(0)).getNodeValue();
					}
				}
				
				auraTypes.add(atModel);
				
				
			}
		}
	}
	
	
	
	public ArrayList<AuraTypeModel> getAuraTypes() {
		return auraTypes;
	}

	public ArrayList<UserXMLModel> getUsers() {
		return users;
	}


	public int getLength() {
		return length;
	}




	public class UserXMLModel extends UserModel {
		public String kmlFile;
		public int startTime;
		public int endTime;
		public String events;
		public String password;
		public double[][] coords;
	}
}
